#pragma once

using namespace System;

namespace SpikingNeuronLib
{
	public ref struct Connection
	{
	public:
		property int PreNeuron;			// index of the pre-synaptic neuron
		property int PostNeuron;		// index of the post-synaptic neuron
		property short Delay;			// axonal delay
		property double Weight;			// synaptic weight
		property double Derivative;		// synaptic derivative
		property short LastDelta;		// the time (msec) of the last change of the synaptic derivative (range limited to 1000 msec)
		property double Integral;		// area under the curve of accumulated synaptic changes

		Connection(int preNeuron, int postNeuron, int delay, double weight)
		{
			this->PreNeuron = preNeuron;
			this->PostNeuron = postNeuron;
			this->Delay = delay;
			this->Weight = weight;
			this->Derivative = 0.0;
			this->LastDelta = 0;
			this->Integral = 0.0;
		}

		Connection(int preNeuron, int postNeuron, int delay, double weight, double derivative)
		{
			this->PreNeuron = preNeuron;
			this->PostNeuron = postNeuron;
			this->Delay = delay;
			this->Weight = weight;
			this->Derivative = derivative;
			this->LastDelta = 0;
			this->Integral = 0.0;
		}

		Connection(int preNeuron, int postNeuron, int delay, bool isExcitatory)
		{
			this->PreNeuron = preNeuron;
			this->PostNeuron = postNeuron;
			this->Delay = delay;
			this->Weight = isExcitatory? 6.0 : -5.0;		// defaults weights for excitatory / inhibitory
			this->Derivative = 0.0;
			this->LastDelta = 0;
			this->Integral = 0.0;
		}

		virtual String^ ToString() override { return String::Format("({0}, {1}, {2}, {3}, {4})", PreNeuron, PostNeuron, Delay, Weight, Derivative); }
	};
}
